/**
YASRACS game galaxy map screen.

YASTACS game
Copyright (C) 2012 Kalman Kiss, kiskami@freemail.hu

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Contact author at: kiskami@freemail.hu or
Hungary, 8900 Zalaegerszeg
Kakukkfu u 4.
*/
module client.GalaxyMap;

import std.stdio;

import ogreint.Timer;
import ogreint.KeyCode;
import ogreint.Entity;
import ogreint.SceneNode;
import ogreint.Light;
import ogreint.Camera;
import ogreint.Vector3;
import ogreint.Degree;
import ogreint.Radian;

import ceguiint.Window;

import iCore;
import ugen.UniversumData;

immutable string galaxymap_layout = "galaxymap.layout";
immutable string galaxymap_info = "GalaxymapRoot/info";
immutable string galaxymap_homebtn = "GalaxymapRoot/homebutton";
immutable string galaxymap_closebtn = "GalaxymapRoot/closebutton";

immutable string info_text_def = 
"Click on a sector to display the map information about it!\n"
~ "Hold the right mouse button, and drag mouse to look around, "
~ "and use the arrow keys to fly!";

immutable KeyCode forward_key = KeyCode.KC_UP;
immutable KeyCode backward_key = KeyCode.KC_DOWN;
immutable KeyCode left_key = KeyCode.KC_LEFT;
immutable KeyCode right_key = KeyCode.KC_RIGHT;

immutable string bluecube_name = "Cube.mesh";
immutable string bluecube_entity_name = "bluecube_entity";

immutable int origo_x = 0;
immutable int origo_y = 0;
immutable int origo_z = 0;
immutable float cube_scale = 2;
immutable float sector_coord_scale = 5;

immutable string pointlight_name = "galaxymap_pointlight";
immutable int pointlight_x = 0;
immutable int pointlight_y = 0;
immutable int pointlight_z = 0;
immutable float pointlight_color_r = 0.98;
immutable float pointlight_color_g = 0.98;
immutable float pointlight_color_b = 0.98;

immutable string camera_name = "GalaxyMapCamera";
immutable float rotate_speed = 0.1;
immutable float move_speed = 1;


// For Sector label display:
// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=ObjectTitle&structure=Cookbook

class GalaxyMap {
	this(iCore core_, Universum ud_) {
		core = core_;
		ud = ud_;
		shown_ = false;
		w = core.gui.loadLayout(galaxymap_layout);

		core.gui.subscribePushButtonEventClicked(galaxymap_homebtn, &homebtn_pushed);
		core.gui.subscribePushButtonEventClicked(galaxymap_closebtn, &closebtn_pushed);

		core.gui.setWidgetText(galaxymap_info, info_text_def);

		createAllSectorSceneNodes();

		createPointLight();

		first_show = true;

		// create camera
		mCamera = core.rendersystem.getCamera(); //core.rendersystem.createCamera(camera_name);
		camvec = new Vector3(0,0,-1);
/*
		movementnode = core.rendersystem.createSceneNode(camera_name ~ "_movement_node");
		camyawnode = core.rendersystem.createSceneNode(camera_name ~ "_camyaw_node");
		camrollnode = core.rendersystem.createSceneNode(camera_name ~ "_camroll_node");
		camnode = core.rendersystem.createSceneNode(camera_name ~ "_camera_node");

		movementnode.addChild(camyawnode);
		camyawnode.addChild(camrollnode);
		camrollnode.addChild(camnode);
*/
//		mCamera.setNearClipDistance(5));
//		mCamera.setFarClipDistance((ud.getSizes()[0] * sector_coord_scale)/2);

//		camnode.attachObject(mCamera);
	}

	void show() {
		if (shown_) return;

		showAllSectorSceneNodes();
		
		core.gui.add(w);
		mouse_shown = core.gui.showMouseCursor();
		shown_ = true;

		if(first_show) {
			first_show = false;
			homebtn_pushed(null);
		}
	}

	void hide() {
		if (!shown_) return;
		
		hideAllSectorSceneNodes();

		core.gui.remove(w);
		core.gui.showMouseCursor(mouse_shown);
		shown_ = false;
	}

	@property bool shown() { return shown_; }

	void input(real elapsedTime) {
		if(!shown_) return;

		dragging_mouse = core.input.rightmousebtnpressed;

		if(core.input.leftmousebtnpressed) {
			// sector info display
		} else // either left click or right click at a time, not both
		if(dragging_mouse) {
			// camera mouselook
			// TODO: limit camera rotation to avoid flip
			auto yaw = new Radian(new Degree(-core.input.relmousex * rotate_speed));
			auto pitch = new Radian(new Degree(-core.input.relmousey * rotate_speed));
			mCamera.yaw(yaw);
            mCamera.pitch(pitch);
		}

		if(core.input.keyPressed(forward_key)) {
			// flying forward
		} else
		if(core.input.keyPressed(backward_key)) {
			// flying backward
		}

		if(core.input.keyPressed(left_key) && !core.input.keyPressed(right_key)) {
			// rotate left
		}
		if(core.input.keyPressed(right_key)&& !core.input.keyPressed(left_key)) {
		   // rotate right
	   }
	}

	bool homebtn_pushed(void *p) {
//		debug writeln("GalaxyMap: home btn pushed.");

		// TODO: place camera to (near) player position in galaxy
		// for now its just the map origo, looking along -z
		mCamera.setPosition(origo_x, origo_y, origo_z);
		mCamera.lookAt(camvec);

		return false;
	}

	bool closebtn_pushed(void *p) {
//		debug writeln("GalaxyMap: home btn pushed.");

		hide();
		return false;
	}

private:

	void createAllSectorSceneNodes() {
		auto rsn = core.rendersystem.getRootSceneNode();
//		debug writeln("GalaxyMap:createAllSectorSceneNodes rsn=", rsn.getName());

		auto galaxy_sizes = ud.getSizes();

		foreach(string snn; ud.sectorNames()) {
			auto sn = rsn.createChildSceneNode(snn);
			auto s = ud.sector(snn);
//			debug writeln("GalaxyMap:createAllSectorSceneNodes sn=", sn.getName()
//							, ", sector=", s.getName());
			auto x = (s.getX() * sector_coord_scale) + origo_x - (galaxy_sizes[0] * sector_coord_scale)/2;
			auto y = (s.getY() * sector_coord_scale ) + origo_y - (galaxy_sizes[1] * sector_coord_scale)/2;
			auto z = (s.getZ() * sector_coord_scale ) + origo_z - (galaxy_sizes[2] * sector_coord_scale)/2;
//			debug writeln("GalaxyMap:createAllSectorSceneNodes node pos:x=",x,",",y,",",z);
			sn.setPosition(x, y, z);
			sn.setScale(cube_scale, cube_scale, cube_scale);
			sn.attachObject(core.rendersystem.createEntity(bluecube_entity_name ~ sn.getName(), bluecube_name));
			sn.setVisible(false);

			nodes[snn] = sn;
		}
	}

	void hideAllSectorSceneNodes() {
		auto rsn = core.rendersystem.getRootSceneNode();
		foreach(SceneNode sn; nodes) {
			sn.setVisible(false);
		}
	}

	void showAllSectorSceneNodes() {
		auto rsn = core.rendersystem.getRootSceneNode();
		foreach(SceneNode sn; nodes) {
			sn.setVisible(true);
		}
	}

	void createPointLight() {
		auto l = core.rendersystem.createLight(pointlight_name);
		l.setType(Light.LightTypes.LT_POINT);
		l.setPosition(pointlight_x, pointlight_y, pointlight_z);
		l.setDiffuseColour(pointlight_color_r, pointlight_color_g, pointlight_color_b);
	}

	iCore core;

	Window w;

	Universum ud;

	bool shown_
		, dragging_mouse
		, mouse_shown;

	SceneNode[string] nodes;

	bool first_show;

	Vector3 camvec;
//	SceneNode movementnode, camyawnode, camrollnode, camnode;

	Camera mCamera;
}
